<?php

namespace plugin\admin\app\controller;

use plugin\admin\app\controller\Base;
use plugin\admin\app\controller\Crud;
use plugin\admin\app\model\User;
use support\exception\BusinessException;
use support\Request;
use support\Response;
use Throwable;
use plugin\admin\app\common\Util;

/**
 * 用户管理 
 */
class UserController extends Crud
{
    /**
     * 不需要登录的方法
     * @var string[]
     */
    protected $noNeedLogin = ['login', 'register','logout', 'captcha'];
    /**
     * @var User
     */
    protected $model = null;

    /**
     * 构造函数
     * @return void
     */
    public function __construct()
    {
        $this->model = new User;
    }

    /**
     * 浏览
     * @return Response
     * @throws Throwable
     */
    public function index(): Response
    {
        return raw_view('user/index');
    }

    /**
     * 插入
     * @param Request $request
     * @return Response
     * @throws BusinessException|Throwable
     */
    public function insert(Request $request): Response
    {
        if ($request->method() === 'POST') {
            return parent::insert($request);
        }
        return raw_view('user/insert');
    }

    /**
     * 更新
     * @param Request $request
     * @return Response
     * @throws BusinessException|Throwable
     */
    public function update(Request $request): Response
    {
        if ($request->method() === 'POST') {
            return parent::update($request);
        }
        return raw_view('user/update');
    }
    /**
     * 检查登录频率限制
     * @param $username
     * @return void
     * @throws BusinessException
     */
    protected function checkLoginLimit($username)
    {
        $limit_log_path = runtime_path().'/login';
        if (!is_dir($limit_log_path)) {
            mkdir($limit_log_path, 0777, true);
        }
        $limit_file = $limit_log_path . '/' . md5($username) . '.limit';
        $time = date('YmdH') . ceil(date('i')/5);
        $limit_info = [];
        if (is_file($limit_file)) {
            $json_str = file_get_contents($limit_file);
            $limit_info = json_decode($json_str, true);
        }

        if (!$limit_info || $limit_info['time'] != $time) {
            $limit_info = [
                'username' => $username,
                'count' => 0,
                'time' => $time
            ];
        }
        $limit_info['count']++;
        file_put_contents($limit_file, json_encode($limit_info));
        if ($limit_info['count'] >= 5) {
            throw new BusinessException('登录失败次数过多，请5分钟后再试');
        }
    }
    /**
     * 解除登录频率限制
     * @param $username
     * @return void
     */
    protected function removeLoginLimit($username)
    {
        $limit_log_path = runtime_path() . '/login';
        $limit_file = $limit_log_path . '/' . md5($username) . '.limit';
        if (is_file($limit_file)) {
            unlink($limit_file);
        }
    }

    protected function checkDatabaseAvailable()
    {
        if (!config('plugin.admin.database')) {
            throw new BusinessException('请重启webman');
        }
    }
    public function logout(Request $request):Response{
        $session = $request->session();
        $session->delete('user');
        return $this->json(0, '退出成功');
    }
    public function login(Request $request):Response{
        if ($request->method()=="POST"){
            $this->checkDatabaseAvailable();
            $captcha = $request->post('captcha', '');
            if (strtolower($captcha) !== session('captcha-login')) {
                return $this->json(1, '验证码错误');
            }
            $request->session()->forget('captcha-login');
            $username = $request->post('username', '');
            $password = $request->post('password', '');
            if (!$username) {
                return $this->json(1, '用户名不能为空');
            }
            $this->checkLoginLimit($username);
            $user = User::where('username', $username)->first();
            if (!$user || !Util::passwordVerify($password, $user->password)) {
                return $this->json(1, '账户不存在或密码错误');
            }
            if ($user->status != 0) {
                return $this->json(1, '当前账户暂时无法登录');
            }
            $user->last_time = date('Y-m-d H:i:s');
            $result = $user->save();
            $this->removeLoginLimit($username);
            if ($result){
                $user = User::where('username', $username)->first();
            }
            $user = $user->toArray();
            $session = $request->session();
            $user['password'] = md5($user['password']);
            $session->set('user', $user);
            $session->set('token', $request->sessionId());
            return $this->json(0, '登录成功', [
                'username' => $user['username'],
                'token' => $request->sessionId(),
                'user_id' => $user['id'],
            ]);
        }
        return raw_view('user/login');
    }
    public function register(Request $request):Response{
        if ($request->method()==="POST"){
            $this->checkDatabaseAvailable();
            $captcha = $request->post('captcha', '');
            if (strtolower($captcha) !== session('captcha-login')) {
                return $this->json(1, '验证码错误');
            }
            $request->session()->forget('captcha-login');
            $username = $request->post('username', '');
            $password = $request->post('password', '');
            if (!$username) {
                return $this->json(1, '用户名不能为空');
            }
            $user = User::where('username', $username)->first();
            if (!empty($user)){
                return $this->json(1, '该账号已被占用');
            }
            if (str_contains($username, "admin")) {
                return $this->json(1, '禁止用户注册admin相关账户');
            }
            if (!$password) {
                return $this->json(1, '密码不能为空');
            }
            $user = new User();
            $user->username = $username;
            $user->password = Util::passwordHash($password);
            $user->nickname = $username;
            $result = $user->save();
            if (!$result){
                return $this->json(1, '注册失败',[$result]);
            }
            return $this->json(0, '注册成功',[$result]);
        }

        return raw_view('user/register');
    }
}
